#ifndef PRINTER_HEADER
#define PRINTER_HEADER

#include "Absyn.h"

/* Certain applications may improve performance by changing the buffer size */
#define BUFFER_INITIAL 2000
/* You may wish to change _L_PAREN or _R_PAREN */
#define _L_PAREN '('
#define _R_PAREN ')'

/* The following are simple heuristics for rendering terminals */
/* You may wish to change them */
void renderCC(Char c);
void renderCS(String s);
void indent(void);
void backup(void);


char* printProgram(Program p);
char* printStatement(Statement p);
char* printQuery(Query p);
char* printNested_query(Nested_query p);
char* printSpecifier(Specifier p);
char* printListProjection(ListProjection p);
char* printProjection(Projection p);
char* printReference(Reference p);
char* printRererence(Rererence p);
char* printColumn_reference(Column_reference p);
char* printDot(Dot p);
char* printListVariable_declaration(ListVariable_declaration p);
char* printVariable_declaration(Variable_declaration p);
char* printOptional_where_clause(Optional_where_clause p);
char* printCondition(Condition p);
char* printPredicate(Predicate p);
char* printComparison_predicate(Comparison_predicate p);
char* printComparison(Comparison p);
char* printScalar_exp(Scalar_exp p);
char* printListAtom(ListAtom p);
char* printAtom(Atom p);
char* printIn_predicate(In_predicate p);
char* printExists_predicate(Exists_predicate p);
char* printBetween_predicate(Between_predicate p);
char* printLike_predicate(Like_predicate p);
char* printOptional_order_by_clause(Optional_order_by_clause p);
char* printListColumn_reference(ListColumn_reference p);
char* printOptional_group_by_clause(Optional_group_by_clause p);
char* printOptional_ordering(Optional_ordering p);
char* printOptional_having_clause(Optional_having_clause p);
char* printAggregate_condition(Aggregate_condition p);
char* printFunction_reference(Function_reference p);
char* printFunction(Function p);

void ppProgram(Program p, int i);
void ppStatement(Statement p, int i);
void ppQuery(Query p, int i);
void ppNested_query(Nested_query p, int i);
void ppSpecifier(Specifier p, int i);
void ppListProjection(ListProjection p, int i);
void ppProjection(Projection p, int i);
void ppReference(Reference p, int i);
void ppRererence(Rererence p, int i);
void ppColumn_reference(Column_reference p, int i);
void ppDot(Dot p, int i);
void ppListVariable_declaration(ListVariable_declaration p, int i);
void ppVariable_declaration(Variable_declaration p, int i);
void ppOptional_where_clause(Optional_where_clause p, int i);
void ppCondition(Condition p, int i);
void ppPredicate(Predicate p, int i);
void ppComparison_predicate(Comparison_predicate p, int i);
void ppComparison(Comparison p, int i);
void ppScalar_exp(Scalar_exp p, int i);
void ppListAtom(ListAtom p, int i);
void ppAtom(Atom p, int i);
void ppIn_predicate(In_predicate p, int i);
void ppExists_predicate(Exists_predicate p, int i);
void ppBetween_predicate(Between_predicate p, int i);
void ppLike_predicate(Like_predicate p, int i);
void ppOptional_order_by_clause(Optional_order_by_clause p, int i);
void ppListColumn_reference(ListColumn_reference p, int i);
void ppOptional_group_by_clause(Optional_group_by_clause p, int i);
void ppOptional_ordering(Optional_ordering p, int i);
void ppOptional_having_clause(Optional_having_clause p, int i);
void ppAggregate_condition(Aggregate_condition p, int i);
void ppFunction_reference(Function_reference p, int i);
void ppFunction(Function p, int i);

char* showProgram(Program p);
char* showStatement(Statement p);
char* showQuery(Query p);
char* showNested_query(Nested_query p);
char* showSpecifier(Specifier p);
char* showListProjection(ListProjection p);
char* showProjection(Projection p);
char* showReference(Reference p);
char* showRererence(Rererence p);
char* showColumn_reference(Column_reference p);
char* showDot(Dot p);
char* showListVariable_declaration(ListVariable_declaration p);
char* showVariable_declaration(Variable_declaration p);
char* showOptional_where_clause(Optional_where_clause p);
char* showCondition(Condition p);
char* showPredicate(Predicate p);
char* showComparison_predicate(Comparison_predicate p);
char* showComparison(Comparison p);
char* showScalar_exp(Scalar_exp p);
char* showListAtom(ListAtom p);
char* showAtom(Atom p);
char* showIn_predicate(In_predicate p);
char* showExists_predicate(Exists_predicate p);
char* showBetween_predicate(Between_predicate p);
char* showLike_predicate(Like_predicate p);
char* showOptional_order_by_clause(Optional_order_by_clause p);
char* showListColumn_reference(ListColumn_reference p);
char* showOptional_group_by_clause(Optional_group_by_clause p);
char* showOptional_ordering(Optional_ordering p);
char* showOptional_having_clause(Optional_having_clause p);
char* showAggregate_condition(Aggregate_condition p);
char* showFunction_reference(Function_reference p);
char* showFunction(Function p);

void shProgram(Program p);
void shStatement(Statement p);
void shQuery(Query p);
void shNested_query(Nested_query p);
void shSpecifier(Specifier p);
void shListProjection(ListProjection p);
void shProjection(Projection p);
void shReference(Reference p);
void shRererence(Rererence p);
void shColumn_reference(Column_reference p);
void shDot(Dot p);
void shListVariable_declaration(ListVariable_declaration p);
void shVariable_declaration(Variable_declaration p);
void shOptional_where_clause(Optional_where_clause p);
void shCondition(Condition p);
void shPredicate(Predicate p);
void shComparison_predicate(Comparison_predicate p);
void shComparison(Comparison p);
void shScalar_exp(Scalar_exp p);
void shListAtom(ListAtom p);
void shAtom(Atom p);
void shIn_predicate(In_predicate p);
void shExists_predicate(Exists_predicate p);
void shBetween_predicate(Between_predicate p);
void shLike_predicate(Like_predicate p);
void shOptional_order_by_clause(Optional_order_by_clause p);
void shListColumn_reference(ListColumn_reference p);
void shOptional_group_by_clause(Optional_group_by_clause p);
void shOptional_ordering(Optional_ordering p);
void shOptional_having_clause(Optional_having_clause p);
void shAggregate_condition(Aggregate_condition p);
void shFunction_reference(Function_reference p);
void shFunction(Function p);

void ppInteger(Integer n, int i);
void ppDouble(Double d, int i);
void ppChar(Char c, int i);
void ppString(String s, int i);
void ppIdent(String s, int i);
void shInteger(Integer n);
void shDouble(Double d);
void shChar(Char c);
void shString(String s);
void shIdent(String s);
void bufAppendS(const char* s);
void bufAppendC(const char c);
void bufReset(void);
void resizeBuffer(void);

#endif

